//
//  AppDelegate+DNJpush.m
//  DNCodeConfuseDemo
//
//  Created by hushuaike on 17/8/22.
//  Copyright © 2017年 hushuaike. All rights reserved.
//

#import "AppDelegate+DNJpush.h"
#import <objc/runtime.h>
#import <UserNotifications/UserNotifications.h>
// iOS10注册APNs所需头文件
#if !(TARGET_IPHONE_SIMULATOR)
#import "JPUSHService.h"
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
#endif

#define isOS_INJPUSH(Version) [[UIDevice currentDevice].systemVersion floatValue] >=Version

NSString * (^DNjPushUUID)();
#if !(TARGET_IPHONE_SIMULATOR)
@interface AppDelegate ()<JPUSHRegisterDelegate>
#else
@interface AppDelegate ()
#endif
/** 极光推送中的详细信息 */
@property (strong, nonatomic, readonly) NSDictionary *UCSJPushNotiInfo;
@end
@implementation AppDelegate (DNJpush)

- (void)jPushConfigApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  withJPushkey:(NSString *)jPushKey jPushUUID:(NSString *(^)())jPushUUID
{
#if !(TARGET_IPHONE_SIMULATOR)
    UCSjPushUUID = [jPushUUID copy];
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
    entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
    if(launchOptions) {//保存
        NSDictionary *  userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if(userInfo){
            self.UCSJPushNotiInfo = userInfo;
        }
    }
    [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
    [JPUSHService setupWithOption:launchOptions appKey:jPushKey
                          channel:@"appStore"
                 apsForProduction:YES
            advertisingIdentifier:nil];
    
    [self setupNotifiers];
#endif
}

// 监听系统生命周期回调，以便将需要的事件传给SDK
- (void)setupNotifiers{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appDidEnterBackgroundNotif:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appWillEnterForeground:)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:nil];
#if !(TARGET_IPHONE_SIMULATOR)
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateAPServiceAlisa) name:kJPFNetworkDidLoginNotification object:nil];
#endif
    
}

#pragma mark - notifiers
- (void)appDidEnterBackgroundNotif:(NSNotification*)notif
{
    !self.UCSAppDidEnterBackground ?: self.UCSAppDidEnterBackground();
}

- (void)appWillEnterForeground:(NSNotification*)notif
{
    
    if(isOS_INJPUSH(10))
    {
        [[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
    }else{
        if([[UIApplication sharedApplication]  respondsToSelector:@selector(cancelAllLocalNotifications)])
        {
            [[UIApplication sharedApplication] performSelector:@selector(cancelAllLocalNotifications)];
        }
    }
    !self.UCSAppWillEnterForeground ? : self.UCSAppWillEnterForeground();
}


- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
#if !(TARGET_IPHONE_SIMULATOR)
    if([self openUCSJPushLog])
    {
        NSLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]);
    }
    [JPUSHService registerDeviceToken:deviceToken];
#endif
}

- (void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    if([self openUCSJPushLog])
    {
        NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
    }
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
#if !(TARGET_IPHONE_SIMULATOR)
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
    // Required
    NSDictionary * userInfo = notification.request.content.userInfo;
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    //增加badge
    [UIApplication sharedApplication].applicationIconBadgeNumber += 1;
    [JPUSHService setBadge:[UIApplication sharedApplication].applicationIconBadgeNumber];
    self.UCSJPushNotiInfo = userInfo;
    NSInteger result = UNNotificationPresentationOptionBadge;
    if(self.UCSWillPresentNotification){
        result = self.UCSWillPresentNotification(userInfo);
    }
    completionHandler(result); // 需要执行这个方法，选择是否提醒用户，有Badge、Sound、Alert三种类型可以选择设置
    
}
#endif



#if !(TARGET_IPHONE_SIMULATOR)
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    // Required
    NSDictionary * userInfo = response.notification.request.content.userInfo;
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
        self.UCSJPushNotiInfo = userInfo;
        if([self openUCSJPushLog])
        {
            NSLog(@"%@",userInfo);
        }
        !self.UCSDidReceiveRemoteNotification ? : self.UCSDidReceiveRemoteNotification(userInfo);
    }
    completionHandler();  // 系统要求执行这个方法
}
#endif

#pragma clang diagnostic pop

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
#if !(TARGET_IPHONE_SIMULATOR)
    // Required, iOS 7 Support
    [JPUSHService handleRemoteNotification:userInfo];
    if(application.applicationState == UIApplicationStateInactive)
    {
        self.UCSJPushNotiInfo = userInfo;
        !self.UCSDidReceiveRemoteNotification ? : self.UCSDidReceiveRemoteNotification(userInfo);
    }
#endif
    completionHandler(UIBackgroundFetchResultNewData);
}

- (void)updateAPServiceAlisa
{
#if !(TARGET_IPHONE_SIMULATOR)
    if(UCSjPushUUID) {
        NSString *uuid = UCSjPushUUID();
        if([self openUCSJPushLog])
        {
            NSLog(@"\n极光推送设置别名:%@",uuid);
        }
        [JPUSHService setTags:nil alias:uuid callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];
    }else{
        if([self openUCSJPushLog]) NSLog(@"请设置不同登录状态下极光推送标识");
    }
#endif
}
- (void)tagsAliasCallback:(int)iResCode tags:(NSSet*)tags alias:(NSString*)alias {
    if(iResCode == 6002) //极光推送更新失败,延迟2秒重试
    {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self updateAPServiceAlisa];
        });
    }
    if([self openUCSJPushLog]) NSLog(@"设置别名结果: %d, \ntags: %@, \nalias: %@\n", iResCode, tags , alias);
}

#pragma makr 分类属性
static const char UCSKJPushNotiInfo;
- (NSDictionary *)UCSJPushNotiInfo
{
    NSDictionary *m =  objc_getAssociatedObject(self, &UCSKJPushNotiInfo);
    return m;
}

- (void)setUCSJPushNotiInfo:(NSDictionary *)jPushNotiInfo
{
    objc_setAssociatedObject(self, &UCSKJPushNotiInfo, jPushNotiInfo, OBJC_ASSOCIATION_RETAIN);
}

static const char UCSOpenUCSJPushLog;

- (BOOL)openUCSJPushLog
{
    NSNumber *flag =  objc_getAssociatedObject(self, &UCSOpenUCSJPushLog);
    return flag.boolValue;
}

- (void)setOpenUCSJPushLog:(BOOL)openUCSJPushLog
{
    objc_setAssociatedObject(self, &UCSOpenUCSJPushLog, [NSNumber numberWithBool:openUCSJPushLog], OBJC_ASSOCIATION_ASSIGN);
}


static const char UCSKWillPresentNotification;

- (NSInteger (^)(NSDictionary *))UCSWillPresentNotification
{
    NSInteger(^temp)(NSDictionary *dict) =  objc_getAssociatedObject(self, &UCSKWillPresentNotification);
    return [temp copy];
}

- (void)setUCSWillPresentNotification:(NSInteger (^)(NSDictionary *))willPresentNotification
{
    objc_setAssociatedObject(self, &UCSKWillPresentNotification, willPresentNotification, OBJC_ASSOCIATION_COPY);
}

static const char UCSKDidReceiveNotificationResponse;

- (void (^)(NSDictionary *))UCSDidReceiveNotificationResponse
{
    void(^temp)(NSDictionary *dict) =  objc_getAssociatedObject(self, &UCSKDidReceiveNotificationResponse);
    return [temp copy];
}

- (void)setUCSDidReceiveNotificationResponse:(void (^)(NSDictionary *))didReceiveNotificationResponse
{
    objc_setAssociatedObject(self, &UCSKDidReceiveNotificationResponse, didReceiveNotificationResponse, OBJC_ASSOCIATION_COPY);
}

static const char UCSKDidReceiveRemoteNotification;

- (void (^)(NSDictionary *))UCSDidReceiveRemoteNotification
{
    void(^temp)(NSDictionary *dict) =  objc_getAssociatedObject(self, &UCSKDidReceiveRemoteNotification);
    return [temp copy];
}

- (void)setUCSDidReceiveRemoteNotification:(void (^)(NSDictionary *))didReceiveRemoteNotification
{
    objc_setAssociatedObject(self, &UCSKDidReceiveRemoteNotification, didReceiveRemoteNotification, OBJC_ASSOCIATION_COPY);
}

static const char UCSKAppDidEnterBackground;

- (void (^)())UCSAppDidEnterBackground
{
    void(^temp)() =  objc_getAssociatedObject(self, &UCSKAppDidEnterBackground);
    return [temp copy];
}

- (void)setUCSAppDidEnterBackground:(void (^)())UCSAppDidEnterBackground
{
    objc_setAssociatedObject(self, &UCSKAppDidEnterBackground, UCSAppDidEnterBackground, OBJC_ASSOCIATION_COPY);
}
static const char UCSKAppWillEnterForeground;
- (void (^)())UCSAppWillEnterForeground
{
    void(^temp)() =  objc_getAssociatedObject(self, &UCSKAppWillEnterForeground);
    return [temp copy];
    
}
- (void)setUCSAppWillEnterForeground:(void (^)())UCSAppWillEnterForeground
{
    objc_setAssociatedObject(self, &UCSKAppWillEnterForeground, UCSAppWillEnterForeground, OBJC_ASSOCIATION_COPY);
}


@end
